package com.cxh.util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * Bean处理工具类
 * @author ChenXH
 */

public class BeanUtils {

	
	/**
	 * 反射，根据当前传入对象实例，属性名，返回执行后的值
	 * 
	 * @param obj
	 * @param fieldName
	 * @return
	 * @throws Exception
	 */
	public static Object getProperty(Object obj, String fieldName) {
		if (obj == null || fieldName == null) {
			return null;
		}
		String m = fieldName.substring(0, 1).toUpperCase();
		String []splits = fieldName.split(",");
		String objectName,propertyName;
		if(splits.length>1){
			String objname = splits[0];   //二级对象名字
			String propname = splits[1];  //二级对象的属性名字
			objectName = "get"+objname;
			propertyName = "get"+propname;
			try {
				try {
					Object oo = obj.getClass().getMethod(objectName, new Class[0]).invoke(obj); //获取二级对象
					if (oo == null){
						return null;
					}
					return oo.getClass().getMethod(propertyName, new Class[0]).invoke(oo);
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				}
			} catch (SecurityException e2) {
				e2.printStackTrace();
			} catch (NoSuchMethodException e2) {
				e2.printStackTrace();
			}
		}else{
			if(Character.isUpperCase(fieldName.charAt(1))==true){
				m=m.toLowerCase();
			}
			m = "get" + m + fieldName.substring(1, fieldName.length());
			try {
				return obj.getClass().getMethod(m, new Class[0]).invoke(obj);
			} catch (Exception e) {
				e.printStackTrace();
				m = fieldName.substring(0, 1).toUpperCase();
				m = "is" + m + fieldName.substring(1, fieldName.length());
				try {
					return obj.getClass().getMethod(m, new Class[0]).invoke(obj);
				} catch (Exception e1) {
				} 
			}
		}
		return null;
	}

	/**
	 * 反射，根据当前传入对象实例，属性名，设置值
	 * 
	 * @param obj
	 * @param fieldName
	 * @param val
	 */
	public static void setProperty(Object obj, String fieldName, Object val) {
		if (obj == null || fieldName == null) {
			return;
		}
		String m = fieldName.substring(0, 1).toUpperCase();
		m = "set" + m + fieldName.substring(1, fieldName.length());
		try {
			Method[] methods = getAllMethods(obj.getClass());
			for (Method method : methods) {
				if (m.equals(method.getName())) {
					method.invoke(obj, val);
					break;
				}
			}
		} catch (Exception e) {
		}
	}
	
	/**
	 * 递归查找所有的属性，包括父类的属性
	 * 
	 * @param object
	 * @return
	 */
	public static Field[] getAllDeclaredFields(Class<?> cla) {

		if (cla != null && cla != Object.class) {
			Field[] fields = cla.getDeclaredFields();

			Field[] resFields = fields;

			Field[] fields_ = getAllDeclaredFields(cla.getSuperclass());

			if (fields_ != null) {
				resFields = new Field[fields.length + fields_.length];
				System.arraycopy(fields, 0, resFields, 0, fields.length);
				System.arraycopy(fields_, 0, resFields, fields.length, fields_.length);
			}

			return resFields;
		}

		return null;
	}
	
	/**
	 * 查找属性，包括父类的属性
	 * 
	 * @param object
	 * @return
	 */
	public static Field getDeclaredFieldByName(Class<?> cla, String fieldName) {
		for(Field f : getAllDeclaredFields(cla)){
			if(f.getName().equals(fieldName))
				return f;
		}
		return null;
	}
	
	/**
	 * 根据方法名获取方法
	 * @param cla
	 * @param name
	 * @return
	 */
	public static Method getMethod(Class<?> cla, String name){
		for(Method m : getAllMethods(cla)){
			if(m.getName().equals(name)){
				return m;
			}
		}
		return null;
	}
	
	/**
	 * 递归获取所有的方法
	 * @param cla
	 * @return
	 */
	public static Method[] getAllMethods(Class<?> cla){
		if (cla != null && cla != Object.class) {
			Method[] methods = cla.getDeclaredMethods();

			Method[] resMethods = methods;

			Method[] methods_ = getAllMethods(cla.getSuperclass());

			if (methods_ != null) {
				resMethods = new Method[methods.length + methods_.length];
				System.arraycopy(methods, 0, resMethods, 0, methods.length);
				System.arraycopy(methods_, 0, resMethods, methods.length, methods_.length);
			}

			return resMethods;
		}
		return null;
	}
}
